package com.google.code.opengw.server.deployment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import com.google.code.opengw.server.Server;
import com.google.code.opengw.server.domain.Domain;
import com.google.code.opengw.server.domain.Publish;
import com.google.code.opengw.server.support.FileUtils;
import com.google.code.opengw.server.support.XMLParser;
import com.google.code.opengw.support.OpenGWException;
import com.google.code.opengw.support.OpenGWLogger;

public class DeploymentOperator {
	public synchronized void deploy(Deployment deployment) throws OpenGWException, SAXException, IOException, ParserConfigurationException{
		Server server = Server.getInstance();
		Publish publish = XMLParser.parsePublish(null, deployment);
		Domain domain = server.getDomain(publish.getDomainName());
		
		if(domain.isPublishNameExists(publish.getPublishName())){
			undeploy(domain.getName(), publish.getPublishName(), true);
			deploy(server, domain, publish, deployment);
		} else {
			deploy(server, domain, publish, deployment);
		}
		
		
	}
	
	private synchronized void deploy(Server server, Domain domain, Publish publish, Deployment deployment) throws OpenGWException{
		OpenGWLogger.addInfo(this.getClass(), "Deploying : " + publish.getDomainName());
		domain.addPublish(publish);
		File publishPath = server.getPublishDirectory(publish.getDomainName(), publish.getPublishName());
		boolean deploymentCompleted = false;
		if(!publishPath.mkdir())
			throw new OpenGWException(OpenGWException.PUBLISH_DIRECTORY_CAN_NOT_CREATED, publishPath);
		try{
			for(FileHolder holder : deployment.getFileList()){
				File file = server.getPublishResourcePath(publish.getDomainName(), publish.getPublishName(), holder.getRelativePath());
				if(holder.isDirectory()){
					file.mkdir();
					OpenGWLogger.addInfo(this.getClass(), "Directory is created : " + file.getName());
				} else {
					OutputStream out = new FileOutputStream(file);
					out.write(holder.getContent());
					out.close();
					OpenGWLogger.addInfo(this.getClass(), "File is written to disk : " + file.getName());
				}
				deploymentCompleted = true;
			}
		} catch (Exception e) {
			try{
				domain.removePublish(deployment.getPublishName());
			} catch (Exception e2) {
			}
			OpenGWLogger.addError(this.getClass(), "Deployment is not completed", e);
		} finally {
			try{
				if(!deploymentCompleted)
					FileUtils.deleteDir(publishPath);
			} catch (Exception e) {
			}
		}
	}
	
	public synchronized void undeploy(String domainName, String publishName, boolean fromDisk) throws OpenGWException{
		OpenGWLogger.addInfo(this.getClass(), "Undeploying : " + publishName);
		Server server = Server.getInstance();
		Domain domain = server.getDomain(domainName);
		domain.removePublish(publishName);
		if(fromDisk) {
			File publishPath = server.getPublishDirectory(domainName, publishName);
			FileUtils.deleteDir(publishPath);
			OpenGWLogger.addInfo(this.getClass(), "Delete files from disk");
		}
	}
}
